package ttelectronic.mobileholder.service;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import ttelectronic.mobileholder.common.MHCommon;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class MHPhoneStateListener extends PhoneStateListener {
	//
	// private BluetoothSocket mSocket;
	private Context mContext;
	private int mLastState;
	private OutputStream mOutput;

	public MHPhoneStateListener(Context context, BluetoothSocket socket,
			int state) {
		super();
		mContext = context;
		mLastState = state;

		try {
			mOutput = socket.getOutputStream();
		} catch (IOException e) {
			Log.d(MHCommon.TAG + " MHPinInformationService",
					"Can not create socket!");
		}
	}

	@Override
	public void onCallStateChanged(int state, String incomingNumber) {
		super.onCallStateChanged(state, incomingNumber);
		PrintWriter pWriter = new PrintWriter(new OutputStreamWriter(mOutput));
		switch (state) {
		case TelephonyManager.CALL_STATE_IDLE: {
			if (mLastState == TelephonyManager.CALL_STATE_RINGING) {
				Log.d(MHCommon.TAG + " MHPhoneStateListener",
						"RING RING to IDLE");
				pWriter.write(MHCommon.POSTMSG_MISSED_CALL);
				pWriter.flush();

			} else if (mLastState == TelephonyManager.CALL_STATE_OFFHOOK) {
				Log.d(MHCommon.TAG + " MHPhoneStateListener", "OFFHOOK to IDLE");
			}
			mLastState = TelephonyManager.CALL_STATE_IDLE;
			break;
		}
		case TelephonyManager.CALL_STATE_OFFHOOK: {
			Log.d(MHCommon.TAG + " MHPhoneStateListener", "OFFHOOK-ing");
			mLastState = TelephonyManager.CALL_STATE_OFFHOOK;
			break;
		}
		case TelephonyManager.CALL_STATE_RINGING: {
			if (mLastState == TelephonyManager.CALL_STATE_IDLE) {
				synchronized (this) {
					MHCommon.PHONE_STATE = 0;
				}
				Log.d(MHCommon.TAG + " MHPhoneStateListener",
						"IDLE to RINGRING");
				String groupName = getGroupNameFromGroupID(getGroupIdFromContactId(getContactIdFromPhoneNumber(incomingNumber)));
				if (groupName.equals(MHCommon.FAVORITE_GROUP_NAME))
					pWriter.write(MHCommon.POSTMSG_FAVORITE);
				else
					pWriter.write(MHCommon.POSTMSG_CALL_INCOMING);
				pWriter.flush();
			}
			mLastState = TelephonyManager.CALL_STATE_RINGING;
			break;
		}

		default:
			break;
		}
	}

	public long getContactIdFromPhoneNumber(String phonenumber) {
		long contactId = 1L;
		// define the columns I want the query to return
		String[] projection = new String[] {
				ContactsContract.PhoneLookup.DISPLAY_NAME,
				ContactsContract.PhoneLookup._ID };
		// encode the phone number and build the filter URI
		Uri contactUri = Uri.withAppendedPath(
				ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
				Uri.encode(phonenumber));

		// query time
		Cursor cursor = mContext.getContentResolver().query(contactUri,
				projection, null, null, null);

		if (cursor.moveToFirst()) {
			// Get values from contacts database:
			contactId = cursor.getLong(cursor
					.getColumnIndex(ContactsContract.PhoneLookup._ID));
			// name = cursor
			// .getString(cursor
			// .getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
		}
		return contactId;
	}

	public long getGroupIdFromContactId(Long contactId) {
		long groupID = 1;
		// int i = 0;
		Uri uri = Data.CONTENT_URI;
		String where = String.format("%s = ? AND %s = ?", Data.MIMETYPE,
				ContactsContract.CommonDataKinds.GroupMembership.CONTACT_ID);

		String[] whereParams = new String[] {
				ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE,
				Long.toString(contactId), };

		String[] selectColumns = new String[] { ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, };

		Cursor groupIdCursor = mContext.getContentResolver().query(uri,
				selectColumns, where, whereParams, null);
		try {
			while (groupIdCursor.moveToNext()) {
				groupID = groupIdCursor.getLong(0);
				return groupID;
			}
			return groupID;
			// return Long.MIN_VALUE; // Has no group ...
		} finally {
			groupIdCursor.close();
		}
	}

	private String getGroupNameFromGroupID(long groupId) {
		String gID = "";

		String[] projection = new String[] { ContactsContract.Groups.TITLE };
		Cursor group = mContext.getContentResolver().query(
				ContactsContract.Groups.CONTENT_URI, projection,
				ContactsContract.Groups._ID + "=" + groupId, null, null);
		if (group != null) {
			while (group.moveToNext()) {
				gID = group.getString(group
						.getColumnIndex(ContactsContract.Groups.TITLE));
				return gID;
			}
		}
		return gID;
	}
}
